package com.ikas.ai.server.module.data.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ikas.ai.consts.MachineAndWorkConditionConst;
import com.ikas.ai.server.module.InitRedis;
import com.ikas.ai.server.module.data.dao.DataMeteDao;
import com.ikas.ai.server.module.data.enums.DataMeteTypeEnum;
import com.ikas.ai.server.module.data.model.BaseMete;
import com.ikas.ai.server.module.data.model.DataMete;
import com.ikas.ai.server.module.data.model.dto.DataMeteQueryDto;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @Description: 工况测点Service
 * @Author: qi.yilai
 * @Date: 2023/5/6 13:54
 * @Version: 1.0.0
 **/
@Service
public class DataMeteService extends ServiceImpl<DataMeteDao, DataMete> {

    @Autowired
    private MeteService meteService;

    @Autowired
    private InitRedis initRedis;

    /**
     * 根据工况名称初始化工况测点表
     *
     * @param wfName
     */
    public void initDataMeteService(String machineNo, String wfName) {
        List<DataMete> dataMeteList = baseMapper.selectDataMeteFromCondition(machineNo, wfName);
        dataMeteList = dataMeteList.stream().distinct().collect(Collectors.toList());
        List<String> meteNames = dataMeteList.stream().map(DataMete::getMeteCode).distinct().collect(Collectors.toList());
        List<BaseMete> metes = meteService.queryMetesByMeteName(meteNames);
        // key是machineNo_meteCode
        Map<String, BaseMete> name2MeteMap = metes.stream().filter(i -> machineNo.equalsIgnoreCase(i.getMachineNo()) || MachineAndWorkConditionConst.COMMON_MACHINE_NO.equalsIgnoreCase(i.getMachineNo())).collect(Collectors.toMap(BaseMete::getMeteCode, Function.identity()));
        dataMeteList.forEach(dm -> {
            BaseMete mete = name2MeteMap.get(dm.getMeteCode());
            if (Objects.nonNull(mete) && Objects.nonNull(mete.getMeteId())) {
                dm.setMeteId(mete.getMeteId());
            }
            if (Objects.isNull(mete)) {
                Optional<BaseMete> first = metes.stream().filter(i -> StringUtils.isNotBlank(i.getMeteCode())).filter(i -> dm.getMeteCode().equals(i.getMeteCode())).findFirst();
                first.ifPresent(baseMete -> dm.setMeteId(baseMete.getMeteId()));
            }
            dm.setCreateTime(new Date());
//            dm.setEarlyCache("step0".equals(dm.getStepName()) ? 1 : 0);
        });
        saveBatch(dataMeteList);
        initRedis.initDataMeteCache();
    }

    /**
     * 工具工况名称删除工具测点
     *
     * @param wfName
     */
    public int removeDataMeteByWfName(String machineNo, String wfName) {
        LambdaQueryWrapper<DataMete> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(DataMete::getMachineNo, machineNo);
        lambdaQueryWrapper.eq(DataMete::getWfName, wfName);
        int count = baseMapper.delete(lambdaQueryWrapper);
//        initRedis.initDataMeteCache();
        return count;
    }


    /**
     * 获取机组、工况对应的执行响应项测点
     *
     * @param machineNo 机组编号
     * @param wfName    工况名称
     * @return 执行响应项测点(只查询响应项)
     */
    public List<DataMete> getDataMeteByMachineNoAndWfName(String machineNo, String wfName) {
        return lambdaQuery().eq(DataMete::getMachineNo, machineNo)
                .eq(DataMete::getWfName, wfName)
                .eq(DataMete::getType, DataMeteTypeEnum.RESPONSE.getCode())
                .ne(DataMete::getStep, 0)
                .list().stream().filter(i -> Objects.nonNull(i.getMeteId())).filter(distinctByVariable(DataMete::getMeteId)).collect(Collectors.toList());
    }

    private static <T> Predicate<T> distinctByVariable(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }


    /**
     * 列表查询
     *
     * @param queryDto
     * @return
     */
    public List<DataMete> listDataMete(DataMeteQueryDto queryDto) {
        return this.lambdaQuery()
                .eq(StringUtils.isNotBlank(queryDto.getMachineNo()), DataMete::getMachineNo, queryDto.getMachineNo())
                .eq(Objects.nonNull(queryDto.getType()), DataMete::getType, queryDto.getType())
                .eq(StringUtils.isNotBlank(queryDto.getMeteCode()), DataMete::getMeteCode, queryDto.getMeteCode())
                .eq(Objects.nonNull(queryDto.getMeteId()), DataMete::getMeteId, queryDto.getMeteId())
                .eq(StringUtils.isNotBlank(queryDto.getWfName()), DataMete::getWfName, queryDto.getWfName())
                .like(StringUtils.isNotBlank(queryDto.getMeteName()), DataMete::getMeteName, queryDto.getMeteName())
                .list();

    }
}
